package com.bookbuf.verify;

import android.text.TextUtils;
import android.util.Log;

import com.bookbuf.verify.idcard.IDCardUtil;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.Hashtable;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


class VerifyImpl {


	public static int verifyNotEmpty (String value) {
		if (TextUtils.isEmpty (value)) {
			return VerifyCode.BS_VERIFY_EMPTY;
		} else {
			return VerifyCode.CODE_SUCCESS;
		}
	}

	/**
	 * 校验手机号码
	 *
	 * @param value
	 * @return
	 */
	public static int verifyPhone (String value) {
		String regular = "^1[0-9]{10}$";
		Pattern regex = Pattern.compile (regular);
		Matcher matcher = regex.matcher (value);
		int code = matcher.matches () ? VerifyCode.CODE_SUCCESS : VerifyCode.BS_VERIFY_PHONE_ILLEGAL;
		return code;
	}

	/**
	 * 校验座机号码
	 *
	 * @param value
	 * @return
	 */
	public static int verifyTelephone (String value) {
		if (TextUtils.isEmpty (value)) {
			return VerifyCode.BS_VERIFY_TELEPHONE_ILLEGAL;
		}
		if (value.length () > 15) {
			return VerifyCode.BS_VERIFY_TELEPHONE_ILLEGAL;
		}
		if (value.length () > 0) {
			String lastchar = value.substring (value.length () - 1);
			if (lastchar.equals ("+") || lastchar.equals ("-")) {
				return VerifyCode.BS_VERIFY_TELEPHONE_ILLEGAL;
			}
		}
		return VerifyCode.CODE_SUCCESS;
	}

	public static int verifyPassword (String value) {
		String regular = "^[a-zA-Z0-9]{6,16}$";
		Pattern regex = Pattern.compile (regular);
		Matcher matcher = regex.matcher (value);
		int code = matcher.matches () ? VerifyCode.CODE_SUCCESS : VerifyCode.BS_VERIFY_PASSWORD_ILLEGAL;
		return code;
	}

	public static int verifyCode (String value) {
		int code = VerifyCode.CODE_SUCCESS;
		if (TextUtils.isEmpty (value)) {
			code = VerifyCode.BS_VERIFY_CODE_CODE_EMPTY;
		} else {
//            String regular = "^[0-9]{6}$";
//            Pattern regex = Pattern.compile(regular);
//            Matcher matcher = regex.matcher(value);
//            code = matcher.matches() ? VerifyCode.CODE_SUCCESS : VerifyCode.BS_VERIFY_CODE_ILLEGAL;
		}
		return code;
	}

	public static int verifyCodeBelongs (String lastReceivedTarget, String useTarget) {

		int code;
		if (TextUtils.isEmpty (lastReceivedTarget)) {
			code = VerifyCode.BS_VERIFY_CODE_UNSEND;
		} else if (TextUtils.equals (lastReceivedTarget, useTarget)) {
			code = VerifyCode.CODE_SUCCESS;
		} else {
			code = VerifyCode.BS_VERIFY_CODE_BELONG_NOT_USER;
		}
		return code;
	}

	// 判断身份证是否合法
	// ---------------------------

	/**
	 * 1、号码的结构<br/>
	 * 公民身份号码是特征组合码，由十七位数字本体码和一位校验码组成。排列顺序从左至右依次为：六位数字地址码，八位数字出生日期码，<br/>
	 * 三位数字顺序码和一位数字校验码。<br/>
	 * 2、地址码(前六位数）<br/>
	 * 表示编码对象常住户口所在县(市、旗、区)的行政区划代码，按GB/T2260的规定执行。<br/>
	 * 3、出生日期码（第七位至十四位）<br/>
	 * 表示编码对象出生的年、月、日，按GB/T7408的规定执行，年、月、日代码之间不用分隔符。<br/>
	 * 4、顺序码（第十五位至十七位）<br/>
	 * 表示在同一地址码所标识的区域范围内，对同年、同月、同日出生的人编定的顺序号，顺序码的奇数分配给男性，偶数分配给女性。<br/>
	 * 5、校验码（第十八位数）<br/>
	 * （1）十七位数字本体码加权求和公式<br/>
	 * S = Sum(Ai * Wi), i = 0, ... , 16 ，先对前17位数字的权求和<br/>
	 * Ai:表示第i位置上的身份证号码数字值<br/>
	 * Wi:表示第i位置上的加权因子<br/>
	 * Wi: 7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4 2<br/>
	 * （2）计算模<br/>
	 * Y = mod(S, 11)<br/>
	 * （3）通过模得到对应的校验码<br/>
	 * Y: 0 1 2 3 4 5 6 7 8 9 10<br/>
	 * 校验码: 1 0 X 9 8 7 6 5 4 3 2<br/>
	 * 所以我们就可以大致写一个函数来校验是否正确了。<br/>
	 * <p>
	 * 功能：身份证的有效验证<br/>
	 *
	 * @param IDStr 身份证号
	 * @return 有效：true 无效：false
	 */
	public static int verifyIDCard (String IDStr) {
		Log.d ("verify", "+ verifyid():" + IDStr);
		// String errorInfo = "";// 记录错误信息
		IDStr = IDStr.toLowerCase ();

		Log.d ("verify", "- verifyid():" + IDStr);

		String[] ValCodeArr = {"1", "0", "x", "9", "8", "7", "6", "5", "4", "3", "2"};
		String[] Wi = {"7", "9", "10", "5", "8", "4", "2", "1", "6", "3", "7", "9", "10", "5", "8", "4", "2"};
		String Ai = "";

		if (TextUtils.isEmpty (IDStr)) {
			return VerifyCode.BS_BIND_IDCRAD_NULL;
		}
		// 忽略大小写
		// ================ 号码的长度 15位或18位 ================
		if (IDStr.length () != 18) {
			// errorInfo = "身份证号码长度应该为18位。";
			// return errorInfo ;
			return VerifyCode.BS_BIND_IDCRAD_ILLAGE;
		}
		// =======================(end)========================

		// ================ 数字 除最后以为都为数字 ================
		Ai = IDStr.substring (0, 17);
		// =======================(end)========================

		// ================ 出生年月是否有效 ================
		String strYear = Ai.substring (6, 10);// 年份
		String strMonth = Ai.substring (10, 12);// 月份
		String strDay = Ai.substring (12, 14);// 月份

		if (!IDCardUtil.isDate (strYear + "-" + strMonth + "-" + strDay)) {
			// errorInfo = "出生日期无效";
			// return errorInfo ;
			return VerifyCode.BS_BIND_IDCRAD_ILLAGE;
		}

		GregorianCalendar gc = new GregorianCalendar ();
		SimpleDateFormat s = new SimpleDateFormat ("yyyy-MM-dd");
		long parseTime = 0;
		try {
			parseTime = s.parse (strYear + "-" + strMonth + "-" + strDay).getTime ();
		} catch (ParseException e) {
			// errorInfo = "出生日期无效";
			// return errorInfo;
			return VerifyCode.BS_BIND_IDCRAD_ILLAGE;
		}
		// 判断年份最小为1900年
		if (Integer.parseInt (strYear) < 1900 || (gc.get (Calendar.YEAR) - Integer.parseInt (strYear)) > 150 || (gc.getTime ().getTime () - parseTime) < 0) {
			// errorInfo = "出生日期不在有效范围内";
			// return errorInfo ;
			return VerifyCode.BS_BIND_IDCRAD_ILLAGE;
		}
		if (Integer.parseInt (strMonth) > 12 || Integer.parseInt (strMonth) == 0) {
			// errorInfo = "月份无效";
			// return errorInfo ;
			return VerifyCode.BS_BIND_IDCRAD_ILLAGE;
		}
		if (Integer.parseInt (strDay) > 31 || Integer.parseInt (strDay) == 0) {
			// errorInfo = "日期无效";
			// return errorInfo ;
			return VerifyCode.BS_BIND_IDCRAD_ILLAGE;
		}
		// =====================(end)=====================

		// ================ 地区码时候有效 ================
		Hashtable<String, String> h = IDCardUtil.GetAreaCode ();
		if (h.get (Ai.substring (0, 2)) == null) {
			// errorInfo = "地区编码错误";
			// return errorInfo ;
			return VerifyCode.BS_BIND_IDCRAD_ILLAGE;
		}
		// ==============================================

		// ================ 判断最后一位的值 ================
		int TotalmulAiWi = 0;
		for (int i = 0; i < 17; i++) {
			TotalmulAiWi = TotalmulAiWi + Integer.parseInt (String.valueOf (Ai.charAt (i))) * Integer.parseInt (Wi[i]);
		}
		int modValue = TotalmulAiWi % 11;
		String strVerifyCode = ValCodeArr[modValue];
		Ai = Ai + strVerifyCode;

		if (IDStr.length () == 18) {
			if (!Ai.equalsIgnoreCase (IDStr)) {
				// errorInfo = "身份证无效，最后一位字母错误";
				// return errorInfo ;
				return VerifyCode.BS_BIND_IDCRAD_ILLAGE;
			}
		}
		// =====================(end)=====================
		// return errorInfo;
		return VerifyCode.CODE_SUCCESS;
	}


	public static int verifyCn (String value) {
		String rex = "^[\u4e00-\u9fa5]+$";
		Pattern pattern = Pattern.compile (rex);
		Matcher matcher = pattern.matcher (value);
		return matcher.matches () ? VerifyCode.CODE_SUCCESS : VerifyCode.BS_CN_ILLAGE;
	}

	/**
	 * 检查汉字（1~4个汉字认为是合法的）
	 *
	 * @param value
	 * @return
	 */
	public static int verifyRealName (String value) {
		final int verifyCN = verifyCn (value);
		if (verifyCN != VerifyCode.CODE_SUCCESS) {
			return verifyCN;
		}
		String rex = "^[\u4e00-\u9fa5]{1,4}$";
		Pattern pattern = Pattern.compile (rex);
		Matcher matcher = pattern.matcher (value);
		return matcher.matches () ? VerifyCode.CODE_SUCCESS : VerifyCode.BS_NAME_TOO_LONG;
	}

}
